package com.demo.pattern.corp.pipeline.executor;

import com.demo.pattern.corp.entity.BasePipelineContext;
import com.demo.pattern.corp.pipeline.handle.IContextHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 管道执行器
 */
@Slf4j
@Component
public class PipelineExecutor {

	/**
	 * 引用 PipelineRouteConfig 中的 pipelineRouteMap
	 */
	@Resource
	private Map<Class<? extends BasePipelineContext>, List<? extends IContextHandler<? super BasePipelineContext>>> pipelineRouteMap;

	/**
	 * 同步处理输入的上下文数据
	 * 如果处理时上下文数据流通到最后一个处理器且最后一个处理器返回 true，则返回 true，否则返回 false
	 *
	 * @param context 输入的上下文数据
	 * @return 处理过程中管道是否畅通，畅通返回 true，不畅通返回 false
	 */
	public boolean handle(BasePipelineContext context) {

		Objects.requireNonNull(context, "上下文数据不能为 null");

		// 拿到数据类型
		Class<? extends BasePipelineContext> dataType = context.getClass();

		// 获取数据处理管道
		List<? extends IContextHandler<? super BasePipelineContext>> pipeline = pipelineRouteMap.get(dataType);

		if (CollectionUtils.isEmpty(pipeline)) {
			log.error("{} 的管道为空", dataType.getSimpleName());
			return false;
		}

		// 管道是否畅通
		boolean lastSuccess = true;

		for (IContextHandler<? super BasePipelineContext> handler : pipeline) {
			try {
				// 当前处理器处理数据，并返回是否继续向下处理
				lastSuccess = handler.handle(context);
			} catch (Throwable ex) {
				lastSuccess = false;
				log.error("[{}] 处理异常，handler={}", context.getClass().getSimpleName(), handler.getClass().getSimpleName(), ex);
			}

			// 不再向下处理
			if (!lastSuccess) {
				break;
			}
		}

		return lastSuccess;
	}
}